package com.kaibo.retrofit;

import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;

import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @author: kaibo
 * @date: 2021/1/13 18:23
 * @GitHub: https://github.com/yuxuelian
 * @qq: 568966289
 * @description:
 */

public class RetrofitClientScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware {

    private ResourceLoader resourceLoader;

    private ClassLoader classLoader;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(EnableRetrofitClient.class.getName()));
        if (attributes == null) {
            return;
        }
        ClassPathRetrofitClientScanner scanner = new ClassPathRetrofitClientScanner(registry, classLoader);
        scanner.registerFilters();
        if (resourceLoader != null) {
            scanner.setResourceLoader(resourceLoader);
        }
        String[] basePackages = getPackagesToScan(attributes);
        if (basePackages.length == 0) {
            StandardAnnotationMetadata standardAnnotationMetadata = (StandardAnnotationMetadata) metadata;
            Class<?> introspectedClass = standardAnnotationMetadata.getIntrospectedClass();
            scanner.doScan(introspectedClass.getPackage().getName());
        } else {
            scanner.doScan(basePackages);
        }
    }

    private String[] getPackagesToScan(AnnotationAttributes attributes) {
        String[] value = attributes.getStringArray("value");
        String[] basePackages = attributes.getStringArray("basePackages");
        Set<String> packagesToScan = new LinkedHashSet<>();
        packagesToScan.addAll(Arrays.asList(value));
        packagesToScan.addAll(Arrays.asList(basePackages));
        return packagesToScan.toArray(new String[0]);
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }


    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }
}
